package edu.ufrj.pesc.softwaregraph;

import java.util.*;

public class SoftwareGraphNode {
		private String name;
		private String path;
		private String type;
		private Date timestamp;
		private Vector<SoftwareGraphEdge> incomingEdges;
		private Vector<SoftwareGraphEdge> outgoingEdges;
		
		public SoftwareGraphNode() {
			
		}
		
		public SoftwareGraphNode(String _name, String _path) {
			this.name = _name;
			this.path = _path;
			this.type = null;
			this.timestamp = null;
			this.incomingEdges = new Vector<SoftwareGraphEdge>();
			this.outgoingEdges = new Vector<SoftwareGraphEdge>();
		}
		
		/**
	    * 
	    * @param e
	    * @return true if the edge was added, false otherwise
	    */ 
		public boolean addEdge(SoftwareGraphEdge e)
		{
			if (e.getFrom() == this)
				outgoingEdges.addElement(e);
			else if (e.getTo() == this)
				incomingEdges.addElement(e);
			else 
				return false;
			return true;
		}
		
		public boolean hasEdge(SoftwareGraphEdge e)
		{
			if (e.getFrom() == this)
				return incomingEdges.contains(e);
			else if (e.getTo() == this)
				return outgoingEdges.contains(e);
			else 
				return false;
		}
		
		// Remove an edge from this vertex
		public boolean remove(SoftwareGraphEdge e)
		{
			if (e.getFrom() == this)
				incomingEdges.removeElement(e);
			else if (e.getTo() == this)
				outgoingEdges.removeElement(e);
			else 
				return false;
			return true;
		}
		
		public int getIncomingEdgeCount()
		{
			return incomingEdges.size();
		}
		
		public SoftwareGraphEdge getIncomingEdge(int i)
		{
			SoftwareGraphEdge e = (SoftwareGraphEdge) incomingEdges.get(i);
			return e;
		}
		
		public int getOutgoingEdgeCount()
		{
			return outgoingEdges.size();
		}
		
		public SoftwareGraphEdge getOutgoingEdge(int i)
		{
			SoftwareGraphEdge e = (SoftwareGraphEdge) outgoingEdges.get(i);
			return e;
		}
		
		// Do we have an edge that goes to dest?
		public SoftwareGraphEdge findEdge(SoftwareGraphNode dest)
		{
			for (int i = 0; i < incomingEdges.size(); i++)
			{
				SoftwareGraphEdge e = (SoftwareGraphEdge)incomingEdges.elementAt(i);
				if (e.getTo() == dest)
					return e;
			}
			return null;
		}	
		
		// Do we have the edge e?  Only looks at sucessors
		public SoftwareGraphEdge findEdge(SoftwareGraphEdge e)
		{
			if (incomingEdges.contains(e))
				return e;
			else
				return null;
		}	
		
		// Do we have an edge to dest?
		public boolean hasEdge(SoftwareGraphNode dest)
		{
			return (findEdge(dest) != null);
		}

		   public String toString()
		   {
		      StringBuffer tmp = new StringBuffer("Vertex(");
		      tmp.append(name);
		      tmp.append(" - ");
		      tmp.append(type);
		      tmp.append("), in:[");
		      for (int i = 0; i < incomingEdges.size(); i++)
		      {
		    	  SoftwareGraphEdge e = (SoftwareGraphEdge) incomingEdges.elementAt(i);
		         if( i > 0 )
		            tmp.append(',');
		         tmp.append('{');
		         tmp.append(e.getFrom().name);
		         tmp.append('}');
		      }
		      tmp.append("], out:[");
		      for (int i = 0; i < outgoingEdges.size(); i++)
		      {
		    	  SoftwareGraphEdge e = (SoftwareGraphEdge) outgoingEdges.elementAt(i);
		         if( i > 0 )
		            tmp.append(',');
		         tmp.append('{');
		         tmp.append(e.getTo().name);
		         tmp.append('}');
		      }
		      tmp.append(']');
		      return tmp.toString();
		   }
		
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public String getPath() {
			return path;
		}
		public void setPath(String path) {
			this.path = path;
		}
		public String getType() {
			return type;
		}
		public void setType(String type) {
			this.type = type;
		}
		public Date getTimestamp() {
			return timestamp;
		}
		public void setTimestamp(Date timestamp) {
			this.timestamp = timestamp;
		}
	
}
